home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Files / Sources / BlitPixieInterface.c next >
Encoding:
Text File  |  2000-10-06  |  53.9 KB  |  1,896 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. //    BlitPixieInterface.c
  3. //
  4. //    Provides a SpriteWorld interface into the BlitPixie routines.
  5. ///--------------------------------------------------------------------------------------
  6.  
  7. #ifndef __SWCOMMON__
  8. #include <SWCommonHeaders.h>
  9. #endif
  10.  
  11. #ifndef __SPRITEFRAME__
  12. #include <SpriteFrame.h>
  13. #endif
  14.  
  15. #ifndef __SPRITEWORLDUTILS__
  16. #include <SpriteWorldUtils.h>
  17. #endif
  18.  
  19. #ifndef __BLITPIXIEINTERFACE__
  20. #include <BlitPixieInterface.h>
  21. #endif
  22.  
  23. #ifndef __BLITPIXIE__
  24. #include <BlitPixieHeader.h>
  25. #endif
  26.  
  27. SInt8                     gSWmmuMode;            //    used when in 24-bit mode on the 68k
  28.  
  29. ///--------------------------------------------------------------------------------------
  30. //    BlitPixieClearDrawProc - 8-bit, 16-bit, and 32-bit DrawProc for 68k and PPC
  31. ///--------------------------------------------------------------------------------------
  32.  
  33. SW_FUNC void BlitPixieClearDrawProc(
  34.     FramePtr srcFrameP,
  35.     FramePtr dstFrameP,
  36.     Rect* srcRect,
  37.     Rect* dstRect)
  38. {
  39.     #pragma unused(srcFrameP,srcRect)    // they're only used to become a DrawProc
  40.     
  41.     RectPtr             frameRectP = &dstFrameP->frameRect;
  42.     Rect                 srcBlitRect = {0,0,0,0};
  43.     Rect                 dstBlitRect = *dstRect;
  44.     long                dstRowBytes = dstFrameP->frameRowBytes;
  45.     int                     numPixelsPerRow,numRowsToCopy;
  46.  
  47.     unsigned long        clearColor;
  48.     
  49.     SW_ASSERT( dstFrameP->framePort != NULL );
  50.     SW_ASSERT( dstFrameP->isFrameLocked );
  51.     SW_ASSERT( dstFrameP->frameDepth >= 8 );
  52.  
  53.     BP_CLIP_RECT(frameRectP, srcBlitRect, dstBlitRect );
  54.                     
  55.     numPixelsPerRow = dstBlitRect.right - dstBlitRect.left;
  56.     numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;
  57.         
  58.         // do interlacing
  59.     if ( dstFrameP->interlacingIsOn )
  60.     {
  61.             // skip first row if it's wrong kind (even/odd)
  62.         if ( ((dstBlitRect.top - frameRectP->top) & 1) == dstFrameP->skipOddLines )
  63.         {
  64.             dstBlitRect.top++;
  65.             numRowsToCopy--;
  66.         }
  67.     
  68.             // calculate rows to blit (half)
  69.         numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  70.         
  71.             // double the rowbytes
  72.         dstRowBytes += dstRowBytes;
  73.     }
  74.  
  75.     if ( numPixelsPerRow <= 0 )
  76.         return;
  77.     if ( numRowsToCopy <= 0 )
  78.         return;
  79.     
  80.         // get pixel value from RGB color
  81.     clearColor = gSWCurrentSpriteWorld->backgroundValue;
  82.         
  83.     START_32_BIT_MODE
  84.  
  85.     BlitPixieClear(
  86.         (UInt8 *) SW_PIXELPTR( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  87.         dstRowBytes,
  88.         SW_PIXELBYTES( dstFrameP, numPixelsPerRow ),
  89.         numRowsToCopy,
  90.         clearColor);
  91.  
  92.     END_32_BIT_MODE
  93. }
  94.  
  95.  
  96. ///--------------------------------------------------------------------------------------
  97. //    BlitPixieRectDrawProc - 8-bit, 16-bit, and 32-bit DrawProc for 68k and PPC
  98. ///--------------------------------------------------------------------------------------
  99.  
  100. SW_FUNC void BlitPixieRectDrawProc(
  101.     FramePtr srcFrameP,
  102.     FramePtr dstFrameP,
  103.     Rect* srcRect,
  104.     Rect* dstRect)
  105. {
  106.     RectPtr             frameRectP = &dstFrameP->frameRect;
  107.     Rect                 srcBlitRect = *srcRect;
  108.     Rect                 dstBlitRect = *dstRect;
  109.     long                srcRowBytes = srcFrameP->frameRowBytes;
  110.     long                dstRowBytes = dstFrameP->frameRowBytes;
  111.     int                     numPixelsPerRow,numRowsToCopy;
  112.     
  113.     SW_ASSERT( srcFrameP->framePort != NULL );
  114.     SW_ASSERT( dstFrameP->framePort != NULL );
  115.     SW_ASSERT( srcFrameP->isFrameLocked && dstFrameP->isFrameLocked );
  116.     SW_ASSERT( dstFrameP->frameDepth >= 8 );
  117.     SW_ASSERT( srcFrameP->frameDepth == dstFrameP->frameDepth );
  118.  
  119.     BP_CLIP_RECT(frameRectP, srcBlitRect, dstBlitRect );
  120.                 
  121.     numPixelsPerRow = dstBlitRect.right - dstBlitRect.left;
  122.     numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;
  123.         
  124.         // do interlacing
  125.     if ( dstFrameP->interlacingIsOn )
  126.     {
  127.             // skip first row if it's wrong kind (even/odd)
  128.         if ( ((dstBlitRect.top - frameRectP->top) & 1) == dstFrameP->skipOddLines )
  129.         {
  130.             srcBlitRect.top++;
  131.             dstBlitRect.top++;
  132.             numRowsToCopy--;
  133.         }
  134.     
  135.             // calculate rows to blit (half)
  136.         numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  137.         
  138.             // double the rowbytes
  139.         srcRowBytes += srcRowBytes;
  140.         dstRowBytes += dstRowBytes;
  141.     }
  142.  
  143.     if ( numPixelsPerRow <= 0 )
  144.         return;
  145.     if ( numRowsToCopy <= 0 )
  146.         return;
  147.         
  148.     START_32_BIT_MODE
  149.  
  150.     BlitPixieRect(
  151.         (UInt8 *) SW_PIXELPTR( srcFrameP, srcBlitRect.left, srcBlitRect.top ),
  152.         (UInt8 *) SW_PIXELPTR( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  153.         srcRowBytes,
  154.         dstRowBytes,
  155.         SW_PIXELBYTES( dstFrameP, numPixelsPerRow ),
  156.         numRowsToCopy );
  157.  
  158.     END_32_BIT_MODE
  159. }
  160.  
  161.  
  162. ///--------------------------------------------------------------------------------------
  163. //    BlitPixieMaskDrawProc - 8-bit, 16-bit, and 32-bit mask DrawProc for 68k and PPC
  164. ///--------------------------------------------------------------------------------------
  165.  
  166. SW_FUNC void BlitPixieMaskDrawProc(
  167.     FramePtr srcFrameP,
  168.     FramePtr dstFrameP,
  169.     Rect* srcRect,
  170.     Rect* dstRect)
  171. {
  172.     RectPtr             frameRectP = &dstFrameP->frameRect;
  173.     Rect                 srcBlitRect = *srcRect;
  174.     Rect                 dstBlitRect = *dstRect;
  175.     unsigned long        srcRowBytes = srcFrameP->frameRowBytes;
  176.     unsigned long        dstRowBytes = dstFrameP->frameRowBytes;
  177.     long                srcBaseOffset;
  178.     int                     numPixelsPerRow,numRowsToCopy;
  179.  
  180.     SW_ASSERT( srcFrameP->framePort != NULL );
  181.     SW_ASSERT( srcFrameP->maskPort != NULL );
  182.     SW_ASSERT( dstFrameP->framePort != NULL );
  183.     SW_ASSERT( srcFrameP->isFrameLocked && dstFrameP->isFrameLocked );
  184.     SW_ASSERT( dstFrameP->frameDepth >= 8 );
  185.     SW_ASSERT( srcFrameP->frameDepth == dstFrameP->frameDepth );
  186.  
  187.     BP_CLIP_RECT(frameRectP, srcBlitRect, dstBlitRect );
  188.                 
  189.     numPixelsPerRow = dstBlitRect.right - dstBlitRect.left;
  190.     numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;
  191.         
  192.         // do interlacing
  193.     if ( dstFrameP->interlacingIsOn )
  194.     {
  195.             // skip first row if it's wrong kind (even/odd)
  196.         if ( ((dstBlitRect.top - frameRectP->top) & 1) == dstFrameP->skipOddLines )
  197.         {
  198.             srcBlitRect.top++;
  199.             dstBlitRect.top++;
  200.             numRowsToCopy--;
  201.         }
  202.     
  203.             // calculate rows to blit (half)
  204.         numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  205.         
  206.             // double the rowbytes
  207.         srcRowBytes += srcRowBytes;
  208.         dstRowBytes += dstRowBytes;
  209.     }
  210.  
  211.     if ( numPixelsPerRow <= 0 )
  212.         return;
  213.     if ( numRowsToCopy <= 0 )
  214.         return;
  215.         
  216.     START_32_BIT_MODE
  217.  
  218.     srcBaseOffset =    SW_ROWBYTES( srcFrameP, srcBlitRect.top ) +
  219.                     SW_PIXELBYTES( srcFrameP, srcBlitRect.left );
  220.     
  221.     BlitPixieMask(
  222.         (UInt8 *) (srcFrameP->frameBaseAddr + srcBaseOffset),
  223.         (UInt8 *) SW_PIXELPTR( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  224.         (UInt8 *) (srcFrameP->maskBaseAddr + srcBaseOffset),
  225.         srcRowBytes,
  226.         dstRowBytes,
  227.         SW_PIXELBYTES( dstFrameP, numPixelsPerRow ),
  228.         numRowsToCopy );
  229.  
  230.  
  231.     END_32_BIT_MODE
  232. }
  233.  
  234. ///--------------------------------------------------------------------------------------
  235. //    BlitPixiePartialMaskDrawProc - 8-bit, 16-bit, and 32-bit mask DrawProc for 68k and PPC
  236. ///--------------------------------------------------------------------------------------
  237.  
  238. SW_FUNC void BlitPixiePartialMaskDrawProc(
  239.     FramePtr srcFrameP,
  240.     FramePtr dstFrameP,
  241.     Rect* srcRect,
  242.     Rect* dstRect)
  243. {
  244.     RectPtr             frameRectP = &dstFrameP->frameRect;
  245.     Rect                 srcBlitRect = *srcRect;
  246.     Rect                 dstBlitRect = *dstRect;
  247.     long                srcRowBytes = srcFrameP->frameRowBytes;
  248.     long                dstRowBytes = dstFrameP->frameRowBytes;
  249.     long                srcBaseOffset;
  250.     int                     numPixelsPerRow,numRowsToCopy;
  251.  
  252.     SW_ASSERT( srcFrameP->framePort != NULL );
  253.     SW_ASSERT( srcFrameP->maskPort != NULL );
  254.     SW_ASSERT( dstFrameP->framePort != NULL );
  255.     SW_ASSERT( srcFrameP->isFrameLocked && dstFrameP->isFrameLocked );
  256.     SW_ASSERT( dstFrameP->frameDepth >= 8 );
  257.     SW_ASSERT( srcFrameP->frameDepth == dstFrameP->frameDepth );
  258.  
  259.     BP_CLIP_RECT(frameRectP, srcBlitRect, dstBlitRect );
  260.                 
  261.     numPixelsPerRow = dstBlitRect.right - dstBlitRect.left;
  262.     numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;
  263.         
  264.         // do interlacing
  265.     if ( dstFrameP->interlacingIsOn )
  266.     {
  267.             // skip first row if it's wrong kind (even/odd)
  268.         if ( ((dstBlitRect.top - frameRectP->top) & 1) == dstFrameP->skipOddLines )
  269.         {
  270.             srcBlitRect.top++;
  271.             dstBlitRect.top++;
  272.             numRowsToCopy--;
  273.         }
  274.     
  275.             // calculate rows to blit (half)
  276.         numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  277.         
  278.             // double the rowbytes
  279.         srcRowBytes += srcRowBytes;
  280.         dstRowBytes += dstRowBytes;
  281.     }
  282.  
  283.     if ( numPixelsPerRow <= 0 )
  284.         return;
  285.     if ( numRowsToCopy <= 0 )
  286.         return;
  287.         
  288.     START_32_BIT_MODE
  289.  
  290.     srcBaseOffset =    SW_ROWBYTES( srcFrameP, srcBlitRect.top ) +
  291.                     SW_PIXELBYTES( srcFrameP, srcBlitRect.left );
  292.     
  293.     BlitPixiePartialMask(
  294.         (UInt8 *) (srcFrameP->frameBaseAddr + srcBaseOffset),
  295.         (UInt8 *) SW_PIXELPTR( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  296.         (UInt8 *) (srcFrameP->maskBaseAddr + srcBaseOffset),
  297.         srcRowBytes,
  298.         dstRowBytes,
  299.         SW_PIXELBYTES( dstFrameP, numPixelsPerRow ),
  300.         numRowsToCopy );
  301.  
  302.     END_32_BIT_MODE
  303. }
  304.  
  305. ///--------------------------------------------------------------------------------------
  306. //    BlitPixieMaskCollisionProc - 8-bit, 16-bit, and 32-bit pixel collision checking
  307. ///--------------------------------------------------------------------------------------
  308.  
  309. SW_FUNC Boolean BlitPixieMaskCollisionProc(
  310.     SpritePtr srcSpriteP,
  311.     SpritePtr dstSpriteP,
  312.     Rect* srcRect,
  313.     Rect* dstRect)
  314. {
  315.     unsigned long     srcBaseOffset,
  316.                     dstBaseOffset;
  317.     unsigned char*    srcPixelPtr;
  318.     unsigned char*    dstPixelPtr;
  319.     int                numPixelsPerRow;
  320.     int                numRows;
  321.     Boolean            collision;
  322.     FramePtr        srcFrameP = srcSpriteP->curFrameP;
  323.     FramePtr         dstFrameP = dstSpriteP->curFrameP;
  324.  
  325.     SW_ASSERT( dstFrameP->frameDepth >= 8 );
  326.     SW_ASSERT( srcFrameP->frameDepth == dstFrameP->frameDepth );
  327.  
  328.     SW_ASSERT( srcRect->right > srcRect->left && srcRect->bottom > srcRect->top );
  329.     SW_ASSERT( dstRect->right > dstRect->left && dstRect->bottom > dstRect->top );
  330.  
  331.     SW_ASSERT( srcRect->right - srcRect->left == dstRect->right - dstRect->left );
  332.     SW_ASSERT( srcRect->bottom - srcRect->top == dstRect->bottom - dstRect->top );
  333.  
  334.     START_32_BIT_MODE
  335.  
  336.             // calculate the offset to the first byte of the sectRect of srcSprite
  337.     srcBaseOffset = SW_ROWBYTES( srcFrameP, srcRect->top ) + SW_PIXELBYTES( srcFrameP, srcRect->left );
  338.             
  339.             // ... and for the dstSprite
  340.     dstBaseOffset = SW_ROWBYTES( dstFrameP, dstRect->top ) + SW_PIXELBYTES( dstFrameP, dstRect->left );
  341.         
  342.             // calculate pointers to the mask pixels within the overlapping sections
  343.     srcPixelPtr = (unsigned char*) (srcFrameP->maskBaseAddr + srcBaseOffset);
  344.     dstPixelPtr = (unsigned char*) (dstFrameP->maskBaseAddr + dstBaseOffset);
  345.         
  346.     numPixelsPerRow = (dstRect->right - dstRect->left);
  347.     numRows = (dstRect->bottom - dstRect->top);
  348.  
  349.     collision = BlitPixieMaskCollision(
  350.                     srcPixelPtr,
  351.                     dstPixelPtr,
  352.                     srcFrameP->frameRowBytes,
  353.                     dstFrameP->frameRowBytes,
  354.                     SW_PIXELBYTES(dstFrameP,numPixelsPerRow),
  355.                     numRows );
  356.     
  357.     END_32_BIT_MODE
  358.  
  359.     return collision;
  360. }
  361.  
  362.  
  363. ///--------------------------------------------------------------------------------------
  364. //    BlitPixieMaskColorDrawProc - 8-bit, 16-bit, and 32-bit mask DrawProc for 68k and PPC
  365. ///--------------------------------------------------------------------------------------
  366.  
  367. SW_FUNC void BlitPixieMaskColorDrawProc(
  368.     FramePtr srcFrameP,
  369.     FramePtr dstFrameP,
  370.     Rect* srcRect,
  371.     Rect* dstRect)
  372. {
  373.     RectPtr             frameRectP = &dstFrameP->frameRect;
  374.     Rect                 srcBlitRect = *srcRect;
  375.     Rect                 dstBlitRect = *dstRect;
  376.     unsigned long        srcRowBytes = srcFrameP->frameRowBytes;
  377.     unsigned long        dstRowBytes = dstFrameP->frameRowBytes;
  378.     long                srcBaseOffset;
  379.     int                     numPixelsPerRow,numRowsToCopy;
  380.     unsigned long        color;
  381.     
  382.     SW_ASSERT( srcFrameP->framePort != NULL );
  383.     SW_ASSERT( srcFrameP->maskPort != NULL );
  384.     SW_ASSERT( dstFrameP->framePort != NULL );
  385.     SW_ASSERT( srcFrameP->isFrameLocked && dstFrameP->isFrameLocked );
  386.     SW_ASSERT( dstFrameP->frameDepth >= 8 );
  387.     SW_ASSERT( srcFrameP->frameDepth == dstFrameP->frameDepth );
  388.     
  389.     if ( dstFrameP->frameDepth < 8 )
  390.         return;
  391.     
  392.     BP_CLIP_RECT(frameRectP, srcBlitRect, dstBlitRect );
  393.                 
  394.     numPixelsPerRow = dstBlitRect.right - dstBlitRect.left;
  395.     numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;
  396.         
  397.         // do interlacing
  398.     if ( dstFrameP->interlacingIsOn )
  399.     {
  400.             // skip first row if it's wrong kind (even/odd)
  401.         if ( ((dstBlitRect.top - frameRectP->top) & 1) == dstFrameP->skipOddLines )
  402.         {
  403.             srcBlitRect.top++;
  404.             dstBlitRect.top++;
  405.             numRowsToCopy--;
  406.         }
  407.     
  408.             // calculate rows to blit (half)
  409.         numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  410.         
  411.             // double the rowbytes
  412.         srcRowBytes += srcRowBytes;
  413.         dstRowBytes += dstRowBytes;
  414.     }
  415.  
  416.     if ( numPixelsPerRow <= 0 )
  417.         return;
  418.     if ( numRowsToCopy <= 0 )
  419.         return;
  420.         
  421.     START_32_BIT_MODE
  422.  
  423.     srcBaseOffset =    SW_ROWBYTES( srcFrameP, srcBlitRect.top ) +
  424.                     SW_PIXELBYTES( srcFrameP, srcBlitRect.left );
  425.     
  426.     color = gSWCurrentSpriteBeingDrawn->colorValue;
  427.  
  428.     BlitPixieMaskColor(
  429.         color,
  430.         (UInt8 *) SW_PIXELPTR( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  431.         (UInt8 *) (srcFrameP->maskBaseAddr + srcBaseOffset),
  432.         srcRowBytes,
  433.         dstRowBytes,
  434.         SW_PIXELBYTES( dstFrameP, numPixelsPerRow ),
  435.         numRowsToCopy );
  436.  
  437.  
  438.     END_32_BIT_MODE
  439. }
  440.  
  441. #pragma mark -
  442.  
  443. ///--------------------------------------------------------------------------------------
  444. //    BlitPixieRLEDrawProc - 8-bit, 16-bit, and 32-bit RLE DrawProc for 68k and PPC
  445. ///--------------------------------------------------------------------------------------
  446.  
  447. SW_FUNC void BlitPixieRLEDrawProc(
  448.     FramePtr srcFrameP,
  449.     FramePtr dstFrameP,
  450.     Rect* srcRect,
  451.     Rect* dstRect)
  452. {
  453.     RectPtr             frameRectP = &dstFrameP->frameRect;
  454.     Rect                 srcBlitRect = *srcRect;
  455.     Rect                 dstBlitRect = *dstRect;
  456.     UInt8                *dstPixel;
  457.     unsigned long        dstRowBytes;
  458.     
  459.     SW_ASSERT( srcFrameP->rleTokenStart != NULL );
  460.     SW_ASSERT( dstFrameP->framePort != NULL );
  461.     SW_ASSERT( srcFrameP->isFrameLocked && dstFrameP->isFrameLocked );
  462.     SW_ASSERT( srcFrameP->frameDepth >= 8 );
  463.     SW_ASSERT( srcFrameP->frameDepth == dstFrameP->frameDepth );
  464.     
  465.     srcBlitRect.right -= srcBlitRect.left;
  466.     srcBlitRect.bottom -= srcBlitRect.top;
  467.     srcBlitRect.left = 0;
  468.     srcBlitRect.top = 0;
  469.     BP_CLIP_RECT(frameRectP, srcBlitRect, dstBlitRect );
  470.                 
  471.     if ( dstBlitRect.left >= dstBlitRect.right )
  472.         return;
  473.     if ( dstBlitRect.top >= dstBlitRect.bottom )
  474.         return;
  475.         
  476.     START_32_BIT_MODE
  477.  
  478.     dstPixel = (UInt8 *) SW_PIXELPTR( dstFrameP, dstBlitRect.left, dstBlitRect.top );
  479.     dstRowBytes = dstFrameP->frameRowBytes;
  480.         
  481.             // do we need to clip ?
  482.     if (    srcBlitRect.right - srcBlitRect.left != srcFrameP->frameRect.right - srcFrameP->frameRect.left ||
  483.             srcBlitRect.bottom - srcBlitRect.top != srcFrameP->frameRect.bottom - srcFrameP->frameRect.top )
  484.     {
  485.             // NOTE: can't use the scanLinePtrArray here!
  486.             //       (we're possibly going outside the destination frame)
  487.         dstPixel -= (srcBlitRect.top * dstRowBytes);
  488.         dstPixel -= SW_PIXELBYTES( dstFrameP, srcBlitRect.left );
  489.         
  490.             // convert pixels to bytes, which the clipping routine expects
  491.         srcBlitRect.left = SW_PIXELBYTES( dstFrameP, srcBlitRect.left );
  492.         srcBlitRect.right = SW_PIXELBYTES( dstFrameP, srcBlitRect.right );
  493.     
  494.         BlitPixieRLEClipped(
  495.             (UInt8 *) srcFrameP->rleTokenStart,
  496.             dstPixel,
  497.             dstRowBytes,
  498.             &srcBlitRect );
  499.     }
  500.     else
  501.     {
  502.         BlitPixieRLE(
  503.             (UInt8 *) srcFrameP->rleTokenStart,
  504.             dstPixel,
  505.             dstRowBytes );
  506.     }
  507.  
  508.     END_32_BIT_MODE
  509. }
  510.  
  511.  
  512. ///--------------------------------------------------------------------------------------
  513. //    BlitPixieRLECollisionProc - handles 8-bit, 16-bit, and 32-bit
  514. ///--------------------------------------------------------------------------------------
  515.  
  516. SW_FUNC Boolean BlitPixieRLECollisionProc(
  517.     SpritePtr srcSpriteP,
  518.     SpritePtr dstSpriteP,
  519.     Rect* srcRect,
  520.     Rect* dstRect)
  521. {
  522.     Boolean        collision;
  523.     FramePtr    srcFrameP = srcSpriteP->curFrameP;
  524.     FramePtr     dstFrameP = dstSpriteP->curFrameP;
  525.     
  526.     SW_ASSERT( srcFrameP->isFrameLocked && dstFrameP->isFrameLocked );
  527.     SW_ASSERT( srcFrameP->rleTokenStart != NULL && dstFrameP->rleTokenStart != NULL );
  528.  
  529.     SW_ASSERT( srcRect->right - srcRect->left == dstRect->right - dstRect->left );
  530.     SW_ASSERT( srcRect->bottom - srcRect->top == dstRect->bottom - dstRect->top );
  531.  
  532.         // convert pixels to bytes, which the collision routine expects
  533.     srcRect->left = SW_PIXELBYTES( srcFrameP, srcRect->left );
  534.     srcRect->right = SW_PIXELBYTES( srcFrameP, srcRect->right );
  535.     dstRect->left = SW_PIXELBYTES( dstFrameP, dstRect->left );
  536.     dstRect->right = SW_PIXELBYTES( dstFrameP, dstRect->right );
  537.  
  538.     collision = BlitPixieRLECollision(
  539.                     (unsigned char *) srcFrameP->rleTokenStart,
  540.                     (unsigned char *) dstFrameP->rleTokenStart,
  541.                     srcRect,
  542.                     dstRect);    
  543.  
  544.     return collision;
  545. }
  546.  
  547. ///--------------------------------------------------------------------------------------
  548. //    BlitPixieRLEColorDrawProc - 8-bit, 16-bit, and 32-bit RLE DrawProc for 68k and PPC
  549. ///--------------------------------------------------------------------------------------
  550.  
  551. SW_FUNC void BlitPixieRLEColorDrawProc(
  552.     FramePtr srcFrameP,
  553.     FramePtr dstFrameP,
  554.     Rect* srcRect,
  555.     Rect* dstRect)
  556. {
  557.     RectPtr             frameRectP = &dstFrameP->frameRect;
  558.     Rect                 srcBlitRect = *srcRect;
  559.     Rect                 dstBlitRect = *dstRect;
  560.     UInt8                *dstPixel;
  561.     unsigned long        dstRowBytes;
  562.     unsigned long        color;
  563.     
  564.     SW_ASSERT( srcFrameP->rleTokenStart != NULL );
  565.     SW_ASSERT( dstFrameP->framePort != NULL );
  566.     SW_ASSERT( srcFrameP->isFrameLocked && dstFrameP->isFrameLocked );
  567.     SW_ASSERT( srcFrameP->frameDepth >= 8 );
  568.     SW_ASSERT( srcFrameP->frameDepth == dstFrameP->frameDepth );
  569.     
  570.     srcBlitRect.right -= srcBlitRect.left;
  571.     srcBlitRect.bottom -= srcBlitRect.top;
  572.     srcBlitRect.left = 0;
  573.     srcBlitRect.top = 0;
  574.     BP_CLIP_RECT(frameRectP, srcBlitRect, dstBlitRect );
  575.                 
  576.     if ( dstBlitRect.left >= dstBlitRect.right )
  577.         return;
  578.     if ( dstBlitRect.top >= dstBlitRect.bottom )
  579.         return;
  580.         
  581.     START_32_BIT_MODE
  582.  
  583.     dstPixel = (UInt8 *) SW_PIXELPTR( dstFrameP, dstBlitRect.left, dstBlitRect.top );
  584.     dstRowBytes = dstFrameP->frameRowBytes;
  585.     
  586.     color = gSWCurrentSpriteBeingDrawn->colorValue;
  587.     
  588.             // do we need to clip ?
  589.     if (    srcBlitRect.right - srcBlitRect.left != srcFrameP->frameRect.right - srcFrameP->frameRect.left ||
  590.             srcBlitRect.bottom - srcBlitRect.top != srcFrameP->frameRect.bottom - srcFrameP->frameRect.top )
  591.     {
  592.             // NOTE: can't use the scanLinePtrArray here!
  593.             //       (we're possibly going outside the destination frame)
  594.         dstPixel -= (srcBlitRect.top * dstRowBytes);
  595.         dstPixel -= SW_PIXELBYTES( dstFrameP, srcBlitRect.left );
  596.         
  597.             // convert pixels to bytes, which the clipping routine expects
  598.         srcBlitRect.left = SW_PIXELBYTES( dstFrameP, srcBlitRect.left );
  599.         srcBlitRect.right = SW_PIXELBYTES( dstFrameP, srcBlitRect.right );
  600.     
  601.         BlitPixieRLEColorClipped(
  602.             (UInt8 *) srcFrameP->rleTokenStart,
  603.             color,
  604.             dstPixel,
  605.             dstRowBytes,
  606.             &srcBlitRect );
  607.     }
  608.     else
  609.     {
  610.         BlitPixieRLEColor(
  611.             (UInt8 *) srcFrameP->rleTokenStart,
  612.             color,
  613.             dstPixel,
  614.             dstRowBytes );
  615.     }
  616.  
  617.     END_32_BIT_MODE
  618. }
  619. ///--------------------------------------------------------------------------------------
  620. //    BlitPixieDoubleRectDrawProc - handles 8-bit, 16-bit, and 32-bit
  621. ///--------------------------------------------------------------------------------------
  622.  
  623. SW_FUNC void BlitPixieDoubleRectDrawProc(
  624.     FramePtr srcFrameP,
  625.     FramePtr dstFrameP,
  626.     Rect* srcRectA,
  627.     Rect* dstRectA,
  628.     Rect* srcRectB,
  629.     Rect* dstRectB)
  630. {
  631.     RectPtr             frameRectP = &dstFrameP->frameRect;
  632.     Rect                srcBlitRectA = *srcRectA,
  633.                         dstBlitRectA = *dstRectA,
  634.                         srcBlitRectB = *srcRectB,
  635.                         dstBlitRectB = *dstRectB;
  636.     long                srcRowBytes = srcFrameP->frameRowBytes;
  637.     long                dstRowBytes = dstFrameP->frameRowBytes;
  638.     BlitPixieOffsetInfo    info;
  639.     int                     numPixelsPerRowA,numPixelsPerRowB,numRowsToCopy;
  640.     
  641.     SW_ASSERT( srcFrameP->isFrameLocked && dstFrameP->isFrameLocked );
  642.     SW_ASSERT( dstFrameP->frameDepth >= 8 );
  643.     SW_ASSERT( srcFrameP->frameDepth == dstFrameP->frameDepth );
  644.     SW_ASSERT( dstRectA->left <= dstRectB->left );
  645.  
  646.     BP_CLIP_RECT(frameRectP, srcBlitRectA, dstBlitRectA );
  647.     BP_CLIP_RECT(frameRectP, srcBlitRectB, dstBlitRectB );
  648.                 
  649.     numRowsToCopy = dstBlitRectA.bottom - dstBlitRectA.top;
  650.         
  651.         // do interlacing
  652.     if ( dstFrameP->interlacingIsOn )
  653.     {
  654.             // skip first row if it's wrong kind (even/odd)
  655.         if ( ((dstBlitRectA.top - frameRectP->top) & 1) == dstFrameP->skipOddLines )
  656.         {
  657.             srcBlitRectA.top++;
  658.             dstBlitRectA.top++;
  659.             srcBlitRectB.top++;
  660.             dstBlitRectB.top++;
  661.             numRowsToCopy--;
  662.         }
  663.     
  664.             // calculate rows to blit (half)
  665.         numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  666.         
  667.             // double the rowbytes
  668.         srcRowBytes += srcRowBytes;
  669.         dstRowBytes += dstRowBytes;
  670.     }
  671.  
  672.     if ( numRowsToCopy <= 0 )
  673.         return;
  674.  
  675.     numPixelsPerRowA = srcBlitRectA.right - srcBlitRectA.left;
  676.     numPixelsPerRowB = srcBlitRectB.right - srcBlitRectB.left;
  677.  
  678.     if ( numPixelsPerRowA <= 0 )
  679.     {
  680.         srcBlitRectA.right = srcBlitRectA.left;
  681.         dstBlitRectA.right = dstBlitRectA.left;
  682.         numPixelsPerRowA = 0;
  683.     }
  684.     if ( numPixelsPerRowB <= 0 )
  685.     {
  686.         srcBlitRectB.right = srcBlitRectB.left;
  687.         dstBlitRectB.right = dstBlitRectB.left;
  688.         numPixelsPerRowB = 0;
  689.     }
  690.  
  691.     if ( numPixelsPerRowA <= 0 && numPixelsPerRowB <= 0 )
  692.         return;
  693.         
  694.     START_32_BIT_MODE
  695.  
  696.         // Calculate offsets from one rect to the next.
  697.     info.srcOffsetAtoB = SW_PIXELBYTES( srcFrameP, srcBlitRectB.left - srcBlitRectA.right );
  698.     info.srcOffsetBtoA = SW_PIXELBYTES( srcFrameP, srcBlitRectA.left - srcBlitRectB.right );
  699.     info.dstOffsetAtoB = SW_PIXELBYTES( dstFrameP, dstBlitRectB.left - dstBlitRectA.right );
  700.     info.dstOffsetBtoA = SW_PIXELBYTES( dstFrameP, dstBlitRectA.left - dstBlitRectB.right );
  701.         // Add offset to next row
  702.     info.srcOffsetBtoA += srcRowBytes;
  703.     info.dstOffsetBtoA += dstRowBytes;
  704.         
  705.     BlitPixieDoubleRects(
  706.         (UInt8 *) SW_PIXELPTR( srcFrameP, srcBlitRectA.left, srcBlitRectA.top ),
  707.         (UInt8 *) SW_PIXELPTR( dstFrameP, dstBlitRectA.left, dstBlitRectA.top ),
  708.         SW_PIXELBYTES( srcFrameP, numPixelsPerRowA ),
  709.         SW_PIXELBYTES( srcFrameP, numPixelsPerRowB ),
  710.         numRowsToCopy,
  711.         &info );
  712.  
  713.     END_32_BIT_MODE
  714. }
  715.  
  716.  
  717. #pragma mark -
  718.  
  719. ///--------------------------------------------------------------------------------------
  720. //    BlitPixieFlipRectDrawProc - 8-bit, 16-bit, and 32-bit
  721. ///--------------------------------------------------------------------------------------
  722.  
  723. SW_FUNC void BlitPixieFlipRectDrawProc(
  724.     FramePtr srcFrameP,
  725.     FramePtr dstFrameP,
  726.     Rect* srcRect,
  727.     Rect* dstRect)
  728. {
  729.     RectPtr             frameRectP = &dstFrameP->frameRect;
  730.     Rect                 srcBlitRect = *srcRect;
  731.     Rect                 dstBlitRect = *dstRect;
  732.     unsigned long        srcRowBytes = srcFrameP->frameRowBytes;
  733.     unsigned long        dstRowBytes = dstFrameP->frameRowBytes;
  734.     int                     numPixelsPerRow, numRowsToCopy;
  735.  
  736.     SW_ASSERT( srcFrameP->framePort != NULL );
  737.     SW_ASSERT( srcFrameP->maskPort != NULL );
  738.     SW_ASSERT( dstFrameP->framePort != NULL );
  739.     SW_ASSERT( srcFrameP->isFrameLocked && dstFrameP->isFrameLocked );
  740.     SW_ASSERT( dstFrameP->frameDepth >= 8 );
  741.     SW_ASSERT( srcFrameP->frameDepth == dstFrameP->frameDepth );
  742.  
  743.     BP_CLIP_RECT(frameRectP, srcBlitRect, dstBlitRect );
  744.                 
  745.     numPixelsPerRow = dstBlitRect.right - dstBlitRect.left;
  746.     numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;
  747.         
  748.         // do interlacing
  749.     if ( dstFrameP->interlacingIsOn )
  750.     {
  751.             // skip first row if it's wrong kind (even/odd)
  752.         if ( ((dstBlitRect.top - frameRectP->top) & 1) == dstFrameP->skipOddLines )
  753.         {
  754.             srcBlitRect.top++;
  755.             dstBlitRect.top++;
  756.             numRowsToCopy--;
  757.         }
  758.     
  759.             // calculate rows to blit (half)
  760.         numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  761.         
  762.             // double the rowbytes
  763.         srcRowBytes += srcRowBytes;
  764.         dstRowBytes += dstRowBytes;
  765.     }
  766.  
  767.     if ( numPixelsPerRow <= 0 )
  768.         return;
  769.     if ( numRowsToCopy <= 0 )
  770.         return;
  771.         
  772.     START_32_BIT_MODE
  773.  
  774.     if ( gSWCurrentSpriteBeingDrawn->flippedVertical )
  775.     {
  776.             // adjust for clipping wo/ flip
  777.         srcBlitRect.top = (srcRect->bottom-1) + (srcRect->top - srcBlitRect.top);
  778.     
  779.         srcRowBytes = -srcRowBytes;
  780.     }
  781.     
  782.     if ( gSWCurrentSpriteBeingDrawn->flippedHorizontal )
  783.     {
  784.             // adjust for clipping wo/ flip
  785.         srcBlitRect.left = srcRect->left + (srcRect->right - srcBlitRect.right);
  786.         
  787.         if ( dstFrameP->frameDepth == 8 )
  788.         {
  789.             BlitPixieFlip8Bit(
  790.                 SW_PIXELPTR8( srcFrameP, srcBlitRect.left, srcBlitRect.top ),
  791.                 SW_PIXELPTR8( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  792.                 srcRowBytes,
  793.                 dstRowBytes,
  794.                 numPixelsPerRow,
  795.                 numRowsToCopy );
  796.         }
  797.         else if ( dstFrameP->frameDepth == 16 )
  798.         {
  799.             BlitPixieFlip16Bit(
  800.                 SW_PIXELPTR16( srcFrameP, srcBlitRect.left, srcBlitRect.top ),
  801.                 SW_PIXELPTR16( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  802.                 srcRowBytes,
  803.                 dstRowBytes,
  804.                 numPixelsPerRow,
  805.                 numRowsToCopy );
  806.         }
  807.         else // if ( dstFrameP->frameDepth == 32 )
  808.         {
  809.             BlitPixieFlip32Bit(
  810.                 SW_PIXELPTR32( srcFrameP, srcBlitRect.left, srcBlitRect.top ),
  811.                 SW_PIXELPTR32( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  812.                 srcRowBytes,
  813.                 dstRowBytes,
  814.                 numPixelsPerRow,
  815.                 numRowsToCopy );
  816.         }
  817.     }
  818.     else
  819.     {
  820.         BlitPixieRect(
  821.             (UInt8 *) SW_PIXELPTR( srcFrameP, srcBlitRect.left, srcBlitRect.top ),
  822.             (UInt8 *) SW_PIXELPTR( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  823.             srcRowBytes,
  824.             dstRowBytes,
  825.             SW_PIXELBYTES( dstFrameP, numPixelsPerRow ),
  826.             numRowsToCopy );
  827.     }
  828.  
  829.     END_32_BIT_MODE
  830. }
  831.  
  832. ///--------------------------------------------------------------------------------------
  833. //    BlitPixieFlipMaskDrawProc - 8-bit, 16-bit, and 32-bit
  834. ///--------------------------------------------------------------------------------------
  835.  
  836. SW_FUNC void BlitPixieFlipMaskDrawProc(
  837.     FramePtr srcFrameP,
  838.     FramePtr dstFrameP,
  839.     Rect* srcRect,
  840.     Rect* dstRect)
  841. {
  842.     RectPtr             frameRectP = &dstFrameP->frameRect;
  843.     Rect                 srcBlitRect = *srcRect;
  844.     Rect                 dstBlitRect = *dstRect;
  845.     unsigned long        srcRowBytes = srcFrameP->frameRowBytes;
  846.     unsigned long        dstRowBytes = dstFrameP->frameRowBytes;
  847.     long                srcBaseOffset;
  848.     int                     numPixelsPerRow,numRowsToCopy;
  849.  
  850.     SW_ASSERT( srcFrameP->framePort != NULL );
  851.     SW_ASSERT( srcFrameP->maskPort != NULL );
  852.     SW_ASSERT( dstFrameP->framePort != NULL );
  853.     SW_ASSERT( srcFrameP->isFrameLocked && dstFrameP->isFrameLocked );
  854.     SW_ASSERT( dstFrameP->frameDepth >= 8 );
  855.     SW_ASSERT( srcFrameP->frameDepth == dstFrameP->frameDepth );
  856.  
  857.     BP_CLIP_RECT(frameRectP, srcBlitRect, dstBlitRect );
  858.                 
  859.     numPixelsPerRow = dstBlitRect.right - dstBlitRect.left;
  860.     numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;
  861.         
  862.         // do interlacing
  863.     if ( dstFrameP->interlacingIsOn )
  864.     {
  865.             // skip first row if it's wrong kind (even/odd)
  866.         if ( ((dstBlitRect.top - frameRectP->top) & 1) == dstFrameP->skipOddLines )
  867.         {
  868.             srcBlitRect.top++;
  869.             dstBlitRect.top++;
  870.             numRowsToCopy--;
  871.         }
  872.     
  873.             // calculate rows to blit (half)
  874.         numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  875.         
  876.             // double the rowbytes
  877.         srcRowBytes += srcRowBytes;
  878.         dstRowBytes += dstRowBytes;
  879.     }
  880.  
  881.     if ( numPixelsPerRow <= 0 )
  882.         return;
  883.     if ( numRowsToCopy <= 0 )
  884.         return;
  885.         
  886.     START_32_BIT_MODE
  887.  
  888.     if ( gSWCurrentSpriteBeingDrawn->flippedVertical )
  889.     {
  890.             // adjust for clipping wo/ flip
  891.         srcBlitRect.top = (srcRect->bottom-1) + (srcRect->top - srcBlitRect.top);
  892.     
  893.         srcRowBytes = -srcRowBytes;
  894.     }
  895.     
  896.     if ( gSWCurrentSpriteBeingDrawn->flippedHorizontal )
  897.     {
  898.             // adjust for clipping wo/ flip
  899.         srcBlitRect.left = srcRect->left + (srcRect->right - srcBlitRect.right);
  900.         
  901.         srcBaseOffset =
  902.             SW_ROWBYTES( srcFrameP, srcBlitRect.top ) +
  903.             SW_PIXELBYTES( srcFrameP, srcBlitRect.left );
  904.  
  905.         if ( dstFrameP->frameDepth == 8 )
  906.         {
  907.             BlitPixieFlipMask8Bit(
  908.                 (UInt8 *) (srcFrameP->frameBaseAddr + srcBaseOffset),
  909.                 SW_PIXELPTR8( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  910.                 (UInt8 *) (srcFrameP->maskBaseAddr + srcBaseOffset),
  911.                 srcRowBytes,
  912.                 dstRowBytes,
  913.                 numPixelsPerRow,
  914.                 numRowsToCopy );
  915.         }
  916.         else if ( dstFrameP->frameDepth == 16 )
  917.         {
  918.             BlitPixieFlipMask16Bit(
  919.                 (UInt16 *) (srcFrameP->frameBaseAddr + srcBaseOffset),
  920.                 SW_PIXELPTR16( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  921.                 (UInt16 *) (srcFrameP->maskBaseAddr + srcBaseOffset),
  922.                 srcRowBytes,
  923.                 dstRowBytes,
  924.                 numPixelsPerRow,
  925.                 numRowsToCopy );
  926.         }
  927.         else // if ( dstFrameP->frameDepth == 32 )
  928.         {
  929.             BlitPixieFlipMask32Bit(
  930.                 (UInt32 *) (srcFrameP->frameBaseAddr + srcBaseOffset),
  931.                 SW_PIXELPTR32( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  932.                 (UInt32 *) (srcFrameP->maskBaseAddr + srcBaseOffset),
  933.                 srcRowBytes,
  934.                 dstRowBytes,
  935.                 numPixelsPerRow,
  936.                 numRowsToCopy );
  937.         }
  938.     }
  939.     else
  940.     {
  941.         srcBaseOffset =
  942.             SW_ROWBYTES( srcFrameP, srcBlitRect.top ) +
  943.             SW_PIXELBYTES( srcFrameP, srcBlitRect.left );
  944.  
  945.         BlitPixieMask(
  946.             (UInt8 *) (srcFrameP->frameBaseAddr + srcBaseOffset),
  947.             (UInt8 *) SW_PIXELPTR( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  948.             (UInt8 *) (srcFrameP->maskBaseAddr + srcBaseOffset),
  949.             srcRowBytes,
  950.             dstRowBytes,
  951.             numPixelsPerRow,
  952.             numRowsToCopy );
  953.     
  954.     }
  955.     
  956.     END_32_BIT_MODE
  957. }
  958.  
  959. ///--------------------------------------------------------------------------------------
  960. //    BlitPixieFlipMaskCollisionProc - 8-bit, 16-bit, and 32-bit pixel collision checking
  961. ///--------------------------------------------------------------------------------------
  962.  
  963. SW_FUNC Boolean BlitPixieFlipMaskCollisionProc(
  964.     SpritePtr srcSpriteP,
  965.     SpritePtr dstSpriteP,
  966.     Rect* srcRect,
  967.     Rect* dstRect)
  968. {
  969.     unsigned long     srcBaseOffset,
  970.                     dstBaseOffset;
  971.     unsigned char*    srcPixelPtr;
  972.     unsigned char*    dstPixelPtr;
  973.     FramePtr        srcFrameP = srcSpriteP->curFrameP;
  974.     FramePtr         dstFrameP = dstSpriteP->curFrameP;
  975.     unsigned long    srcRowBytes = srcFrameP->frameRowBytes;
  976.     unsigned long    dstRowBytes = dstFrameP->frameRowBytes;
  977.     short            numBytesPerRow;
  978.     short            numRows;
  979.     Boolean            collision;
  980.     
  981.     SW_ASSERT( dstFrameP->frameDepth >= 8 );
  982.     SW_ASSERT( srcFrameP->frameDepth == dstFrameP->frameDepth );
  983.  
  984.     SW_ASSERT( srcRect->right > srcRect->left && srcRect->bottom > srcRect->top );
  985.     SW_ASSERT( dstRect->right > dstRect->left  && dstRect->bottom > dstRect->top );
  986.  
  987.     SW_ASSERT( srcRect->right - srcRect->left == dstRect->right - dstRect->left );
  988.     SW_ASSERT( srcRect->bottom - srcRect->top == dstRect->bottom - dstRect->top );
  989.  
  990.     START_32_BIT_MODE
  991.  
  992.             // calculate the offset to the first byte of the sectRect of srcSprite
  993.     srcBaseOffset = SW_ROWBYTES( srcFrameP, srcRect->top ) + SW_PIXELBYTES( srcFrameP, srcRect->left );
  994.             
  995.             // ... and for the dstSprite
  996.     dstBaseOffset = SW_ROWBYTES( dstFrameP, dstRect->top ) + SW_PIXELBYTES( dstFrameP, dstRect->left );
  997.         
  998.             // calculate pointers to the mask pixels within the overlapping sections
  999.     srcPixelPtr = (unsigned char*) (srcFrameP->maskBaseAddr + srcBaseOffset);
  1000.     dstPixelPtr = (unsigned char*) (dstFrameP->maskBaseAddr + dstBaseOffset);
  1001.         
  1002.             // calculate the number of bytes in a row
  1003.     numBytesPerRow = SW_PIXELBYTES( dstFrameP, (dstRect->right - dstRect->left) );
  1004.     
  1005.     numRows = (dstRect->bottom - dstRect->top);
  1006.  
  1007.     if ( srcSpriteP->flippedVertical )
  1008.     {
  1009.         srcPixelPtr += (numRows-1) * srcRowBytes;
  1010.         srcRowBytes = -srcRowBytes;
  1011.     }
  1012.     else if ( dstSpriteP->flippedVertical )
  1013.     {
  1014.         dstPixelPtr += (numRows-1) * dstRowBytes;
  1015.         dstRowBytes = -dstRowBytes;
  1016.     }
  1017.  
  1018.     if ( srcSpriteP->flippedHorizontal && !dstSpriteP->flippedHorizontal )
  1019.     {
  1020.             // change the order src<->dst
  1021.         collision = BlitPixieFlipMaskCollision(
  1022.                     dstPixelPtr,
  1023.                     srcPixelPtr,
  1024.                     dstRowBytes,
  1025.                     srcRowBytes,
  1026.                     numBytesPerRow,
  1027.                     numRows );
  1028.     }
  1029.     else if ( dstSpriteP->flippedHorizontal && !srcSpriteP->flippedHorizontal )
  1030.     {
  1031.         collision = BlitPixieFlipMaskCollision(
  1032.                     srcPixelPtr,
  1033.                     dstPixelPtr,
  1034.                     srcRowBytes,
  1035.                     dstRowBytes,
  1036.                     numBytesPerRow,
  1037.                     numRows );
  1038.     }
  1039.     else
  1040.     {
  1041.         collision = BlitPixieMaskCollision(
  1042.                     srcPixelPtr,
  1043.                     dstPixelPtr,
  1044.                     srcRowBytes,
  1045.                     dstRowBytes,
  1046.                     numBytesPerRow,
  1047.                     numRows );
  1048.     }
  1049.     END_32_BIT_MODE
  1050.  
  1051.     return collision;
  1052. }
  1053.  
  1054. ///--------------------------------------------------------------------------------------
  1055. //    BlitPixieMaskColorDrawProc - 8-bit, 16-bit, and 32-bit mask DrawProc for 68k and PPC
  1056. ///--------------------------------------------------------------------------------------
  1057.  
  1058. SW_FUNC void BlitPixieFlipMaskColorDrawProc(
  1059.     FramePtr srcFrameP,
  1060.     FramePtr dstFrameP,
  1061.     Rect* srcRect,
  1062.     Rect* dstRect)
  1063. {
  1064.     RectPtr             frameRectP = &dstFrameP->frameRect;
  1065.     Rect                 srcBlitRect = *srcRect;
  1066.     Rect                 dstBlitRect = *dstRect;
  1067.     unsigned long        srcRowBytes = srcFrameP->frameRowBytes;
  1068.     unsigned long        dstRowBytes = dstFrameP->frameRowBytes;
  1069.     long                srcBaseOffset;
  1070.     int                     numPixelsPerRow,numRowsToCopy;
  1071.     unsigned long        color;
  1072.     
  1073.     SW_ASSERT( srcFrameP->framePort != NULL );
  1074.     SW_ASSERT( srcFrameP->maskPort != NULL );
  1075.     SW_ASSERT( dstFrameP->framePort != NULL );
  1076.     SW_ASSERT( srcFrameP->isFrameLocked && dstFrameP->isFrameLocked );
  1077.     SW_ASSERT( dstFrameP->frameDepth >= 8 );
  1078.     SW_ASSERT( srcFrameP->frameDepth == dstFrameP->frameDepth );
  1079.     
  1080.     if ( dstFrameP->frameDepth < 8 )
  1081.         return;
  1082.     
  1083.     BP_CLIP_RECT(frameRectP, srcBlitRect, dstBlitRect );
  1084.                 
  1085.     numPixelsPerRow = dstBlitRect.right - dstBlitRect.left;
  1086.     numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;
  1087.         
  1088.         // do interlacing
  1089.     if ( dstFrameP->interlacingIsOn )
  1090.     {
  1091.             // skip first row if it's wrong kind (even/odd)
  1092.         if ( ((dstBlitRect.top - frameRectP->top) & 1) == dstFrameP->skipOddLines )
  1093.         {
  1094.             srcBlitRect.top++;
  1095.             dstBlitRect.top++;
  1096.             numRowsToCopy--;
  1097.         }
  1098.     
  1099.             // calculate rows to blit (half)
  1100.         numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  1101.         
  1102.             // double the rowbytes
  1103.         srcRowBytes += srcRowBytes;
  1104.         dstRowBytes += dstRowBytes;
  1105.     }
  1106.  
  1107.     if ( numPixelsPerRow <= 0 )
  1108.         return;
  1109.     if ( numRowsToCopy <= 0 )
  1110.         return;
  1111.         
  1112.     START_32_BIT_MODE
  1113.  
  1114.     color = gSWCurrentSpriteBeingDrawn->colorValue;
  1115.  
  1116.     if ( gSWCurrentSpriteBeingDrawn->flippedVertical )
  1117.     {
  1118.             // adjust for clipping wo/ flip
  1119.         srcBlitRect.top = (srcRect->bottom-1) + (srcRect->top - srcBlitRect.top);
  1120.     
  1121.         srcRowBytes = -srcRowBytes;
  1122.     }
  1123.     
  1124.     if ( gSWCurrentSpriteBeingDrawn->flippedHorizontal )
  1125.     {
  1126.             // adjust for clipping wo/ flip
  1127.         srcBlitRect.left = srcRect->left + (srcRect->right - srcBlitRect.right);
  1128.         
  1129.         srcBaseOffset =
  1130.             SW_ROWBYTES( srcFrameP, srcBlitRect.top ) +
  1131.             SW_PIXELBYTES( srcFrameP, srcBlitRect.left );
  1132.  
  1133.         BlitPixieFlipMaskColor(
  1134.             color,
  1135.             (UInt8 *) SW_PIXELPTR( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  1136.             (UInt8 *) (srcFrameP->maskBaseAddr + srcBaseOffset),
  1137.             srcRowBytes,
  1138.             dstRowBytes,
  1139.             SW_PIXELBYTES( dstFrameP, numPixelsPerRow ),
  1140.             numRowsToCopy );
  1141.     }
  1142.     else
  1143.     {
  1144.         srcBaseOffset =
  1145.             SW_ROWBYTES( srcFrameP, srcBlitRect.top ) +
  1146.             SW_PIXELBYTES( srcFrameP, srcBlitRect.left );
  1147.  
  1148.         BlitPixieMaskColor(
  1149.             color,
  1150.             (UInt8 *) SW_PIXELPTR( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  1151.             (UInt8 *) (srcFrameP->maskBaseAddr + srcBaseOffset),
  1152.             srcRowBytes,
  1153.             dstRowBytes,
  1154.             SW_PIXELBYTES( dstFrameP, numPixelsPerRow ),
  1155.             numRowsToCopy );
  1156.     }
  1157.  
  1158.     END_32_BIT_MODE
  1159. }
  1160.  
  1161. #pragma mark -
  1162.  
  1163. #pragma mark [68k only routines:]
  1164.  
  1165. ///--------------------------------------------------------------------------------------
  1166. //    BlitPixieCompiledSpriteDrawProc - 68k only, just stubs on PPC
  1167. ///--------------------------------------------------------------------------------------
  1168.  
  1169. SW_FUNC void BlitPixieCompiledSpriteDrawProc(
  1170.     FramePtr srcFrameP,
  1171.     FramePtr dstFrameP,
  1172.     Rect *srcRect,
  1173.     Rect *dstRect)
  1174. {
  1175. #if SW_PPC
  1176. #pragma unused(srcFrameP, dstFrameP, srcRect, dstRect)
  1177.     SW_ASSERT(SW_68K);
  1178. #else
  1179.     RectPtr             frameRectP = &dstFrameP->frameRect;
  1180.     Rect                 srcBlitRect = *srcRect;
  1181.     Rect                 dstBlitRect = *dstRect;
  1182.     
  1183.     SW_ASSERT( srcFrameP->isFrameLocked && dstFrameP->isFrameLocked );
  1184.     SW_ASSERT( dstFrameP->frameDepth >= 8 );
  1185.     SW_ASSERT( srcFrameP->frameDepth == dstFrameP->frameDepth );
  1186.  
  1187.         // we first check to see if any clipping will be necessary, then
  1188.         // we determine whether or not we can use the compiled blitter. we must
  1189.         // do this since the compiled blitter cannot handle clipping.
  1190.     BP_CLIP_RECT(frameRectP, srcBlitRect, dstBlitRect );
  1191.                 
  1192.         // Make sure height is valid
  1193.     if (dstBlitRect.bottom <= dstBlitRect.top)
  1194.         return;
  1195.         // Make sure width is valid
  1196.     if (dstBlitRect.right <= dstBlitRect.left)
  1197.         return;
  1198.         
  1199.     START_32_BIT_MODE
  1200.  
  1201.         // If we didn't have to clip the sprite, we can call the compiled blitter.
  1202.         // Hopefully this will be the most common case (i.e. the sprites will be entirely
  1203.         // on the screen more often than not)
  1204.     if ( BP_EQUAL_RECT(srcBlitRect, srcFrameP->frameRect ) )
  1205.     {
  1206.         BlitFuncPtr        blitter = (BlitFuncPtr) srcFrameP->frameBlitterP;
  1207.         
  1208.         SW_ASSERT(blitter != NULL);
  1209.  
  1210.         (*blitter)(
  1211.             srcFrameP->frameRowBytes,
  1212.             dstFrameP->frameRowBytes,
  1213.             SW_PIXELPTR( srcFrameP, srcBlitRect.left, srcBlitRect.top ),
  1214.             SW_PIXELPTR( dstFrameP, dstBlitRect.left, dstBlitRect.top ) );
  1215.     }
  1216.     else
  1217.     {
  1218.         long    srcBaseOffset;
  1219.         int        numPixelsPerRow,numRowsToCopy;
  1220.  
  1221.         srcBaseOffset =    SW_ROWBYTES( srcFrameP, srcBlitRect.top ) +
  1222.                         SW_PIXELBYTES( srcFrameP, srcBlitRect.left );
  1223.     
  1224.         numPixelsPerRow = dstBlitRect.right - dstBlitRect.left;
  1225.         numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;
  1226.  
  1227.         SW_ASSERT(srcFrameP->maskBaseAddr != NULL);
  1228.  
  1229.         BlitPixieMask(
  1230.             (UInt8 *) (srcFrameP->frameBaseAddr + srcBaseOffset),
  1231.             (UInt8 *) SW_PIXELPTR( dstFrameP, dstBlitRect.left, dstBlitRect.top ),
  1232.             (UInt8 *) (srcFrameP->maskBaseAddr + srcBaseOffset),
  1233.             srcFrameP->frameRowBytes,
  1234.             dstFrameP->frameRowBytes,
  1235.             SW_PIXELBYTES( dstFrameP, numPixelsPerRow ),
  1236.             numRowsToCopy );
  1237.     }
  1238.     
  1239.     END_32_BIT_MODE
  1240. #endif
  1241. }
  1242.  
  1243.  
  1244. // The all-bit DrawProcs and definitions follow. These are blitters for 
  1245. // 68k only, but will work in any depth, including 1-bit, 2-bits, and 4-bits.
  1246.  
  1247. ///--------------------------------------------------------------------------------------
  1248. //    BlitPixieAllBitRectDrawProc
  1249. ///--------------------------------------------------------------------------------------
  1250.  
  1251. SW_FUNC void BlitPixieAllBitRectDrawProc(
  1252.     FramePtr srcFrameP,
  1253.     FramePtr dstFrameP,
  1254.     Rect* srcRect,
  1255.     Rect* dstRect)
  1256. {
  1257. #if SW_PPC
  1258. #pragma unused(srcFrameP, dstFrameP, srcRect, dstRect)
  1259.     SW_ASSERT(SW_68K);
  1260. #else
  1261.     Rect                srcBlitRect = *srcRect;
  1262.     Rect                dstBlitRect = *dstRect;
  1263.     RectPtr                frameRect = &dstFrameP->frameRect;
  1264.     Boolean                interlaced = dstFrameP->interlacingIsOn;
  1265.     unsigned long        numBytesPerRow;
  1266.     unsigned long         numRowsToCopy;
  1267.     unsigned long        srcOffset;
  1268.     unsigned long        dstOffset;
  1269.     short                b1, b2;
  1270.     short                pixelSize;
  1271.     short                srcBitOffset,dstBitOffset,remainBits;
  1272.     
  1273.     SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
  1274.     SW_ASSERT(srcFrameP->frameDepth == dstFrameP->frameDepth);
  1275.     
  1276.     BP_CLIP_RECT(frameRect, srcBlitRect, dstBlitRect );
  1277.  
  1278.         // Make sure height is valid
  1279.     if (dstBlitRect.bottom <= dstBlitRect.top)
  1280.         return;
  1281.         // Make sure width is valid
  1282.     if (dstBlitRect.right <= dstBlitRect.left)
  1283.         return;
  1284.     
  1285.     pixelSize = dstFrameP->frameDepth;
  1286.     switch ( pixelSize )
  1287.     {
  1288.         case 1:        b1 = 5;        break;        // 1-bit:  32 pixels per long ( 1 << 5 == 32)
  1289.         case 2:        b1 = 4;        break;        // 2-bit:  16 pixels per long ( 1 << 4 == 16)
  1290.         case 4:        b1 = 3;        break;        // 4-bit:   8 pixels per long ( 1 << 3 ==  8)
  1291.         case 8:        b1 = 2;        break;        // 8-bit:   4 pixels per long ( 1 << 2 ==  4)
  1292.         case 16:    b1 = 1;        break;        // 16-bit:  2 pixels per long ( 1 << 1 ==  2)
  1293.         case 32:    b1 = 0;        break;        // 32-bit:  1 pixels per long ( 1 << 0 ==  1)
  1294.  
  1295.         default:                return;        // unknown depth, abort
  1296.     }
  1297.     
  1298.     b2 = 5 - b1;
  1299.     
  1300.         // calculate any odd (non-byte) number of bits
  1301.     srcBitOffset = ((srcFrameP->worldRectOffset + srcBlitRect.left) << b2) & 31;
  1302.     dstBitOffset = ((dstFrameP->worldRectOffset + dstBlitRect.left) << b2) & 31;
  1303.     remainBits = ((dstBlitRect.right - dstBlitRect.left) << b2) & 31;
  1304.             
  1305.     // calculate the number of bytes to blit
  1306.     numBytesPerRow = ((dstBlitRect.right - dstBlitRect.left) >> b1) * sizeof(long);
  1307.     
  1308.     // calculate the number of rows to blit
  1309.     numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;
  1310.  
  1311.     // calculate the row offsets
  1312.     srcOffset = srcFrameP->frameRowBytes;
  1313.     dstOffset = dstFrameP->frameRowBytes;
  1314.  
  1315.     if ( interlaced )
  1316.     {
  1317.         // skip first row if it's wrong kind (even/odd)
  1318.         if ( ((dstBlitRect.top - frameRect->top) & 1) == dstFrameP->skipOddLines )
  1319.         {
  1320.             srcBlitRect.top++;
  1321.             dstBlitRect.top++;
  1322.             numRowsToCopy--;
  1323.         }
  1324.         
  1325.         numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  1326.         if (numRowsToCopy < 1)
  1327.             return;
  1328.  
  1329.             // Double the row offsets since we're skipping every other line
  1330.         srcOffset += srcOffset;
  1331.         dstOffset += dstOffset;
  1332.     }
  1333.     
  1334.         // The offsets push the pixel pointer from the end of one row
  1335.         // to the beginning of the next. 
  1336.     srcOffset -= numBytesPerRow;
  1337.     dstOffset -= numBytesPerRow;
  1338.     
  1339.     START_32_BIT_MODE
  1340.     
  1341.     BlitPixieAllBitRect(
  1342.         (UInt8 *) (srcFrameP->frameBaseAddr + SW_ROWBYTES(srcFrameP,srcBlitRect.top) + ((srcBlitRect.left >> b1) * sizeof(long)) ),
  1343.         (UInt8 *) (dstFrameP->frameBaseAddr + SW_ROWBYTES(dstFrameP,dstBlitRect.top) + ((dstBlitRect.left >> b1) * sizeof(long)) ),
  1344.         srcOffset,
  1345.         dstOffset,
  1346.         numBytesPerRow,
  1347.         numRowsToCopy,
  1348.         srcBitOffset,
  1349.         dstBitOffset,
  1350.         remainBits
  1351.         );
  1352.  
  1353.     END_32_BIT_MODE
  1354. #endif
  1355. }
  1356.  
  1357.  
  1358. ///--------------------------------------------------------------------------------------
  1359. //    BlitPixieAllBitMaskDrawProc
  1360. ///--------------------------------------------------------------------------------------
  1361.  
  1362. SW_FUNC void BlitPixieAllBitMaskDrawProc(
  1363.     FramePtr srcFrameP,
  1364.     FramePtr dstFrameP,
  1365.     Rect* srcRect,
  1366.     Rect* dstRect)
  1367. {
  1368. #if SW_PPC
  1369. #pragma unused(srcFrameP, dstFrameP, srcRect, dstRect)
  1370.     SW_ASSERT(SW_68K);
  1371. #else
  1372.     Rect                srcBlitRect = *srcRect;
  1373.     Rect                dstBlitRect = *dstRect;
  1374.     RectPtr                frameRect = &dstFrameP->frameRect;
  1375.     Boolean                interlaced = dstFrameP->interlacingIsOn;
  1376.     unsigned long        srcBaseOffset;
  1377.     unsigned long        numBytesPerRow;
  1378.     unsigned long         numRowsToCopy;
  1379.     unsigned long        srcOffset;
  1380.     unsigned long        dstOffset;
  1381.     short                pixelSize, b1, b2;
  1382.     short                srcBitOffset,dstBitOffset,remainBits;
  1383.     
  1384.     SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
  1385.     SW_ASSERT(srcFrameP->maskPort != NULL);
  1386.     
  1387.     BP_CLIP_RECT(frameRect, srcBlitRect, dstBlitRect );
  1388.  
  1389.         // Make sure height is valid
  1390.     if (dstBlitRect.bottom <= dstBlitRect.top)
  1391.         return;
  1392.         // Make sure width is valid
  1393.     if (dstBlitRect.right <= dstBlitRect.left)
  1394.         return;
  1395.         
  1396.     pixelSize = dstFrameP->frameDepth;
  1397.     switch ( pixelSize )
  1398.     {
  1399.         case 1:        b1 = 5;        break;        // 1-bit:  32 pixels per long ( 1 << 5 == 32)
  1400.         case 2:        b1 = 4;        break;        // 2-bit:  16 pixels per long ( 1 << 4 == 16)
  1401.         case 4:        b1 = 3;        break;        // 4-bit:   8 pixels per long ( 1 << 3 ==  8)
  1402.         case 8:        b1 = 2;        break;        // 8-bit:   4 pixels per long ( 1 << 2 ==  4)
  1403.         case 16:    b1 = 1;        break;        // 16-bit:  2 pixels per long ( 1 << 1 ==  2)
  1404.         case 32:    b1 = 0;        break;        // 32-bit:  1 pixels per long ( 1 << 0 ==  1)
  1405.  
  1406.         default:                return;        // unknown depth, abort
  1407.     }
  1408.     b2 = 5 - b1;
  1409.  
  1410.         // calculate any odd (non-byte) number of bits
  1411.     srcBitOffset = ((srcFrameP->worldRectOffset + srcBlitRect.left) << b2) & 31;
  1412.     dstBitOffset = ((dstFrameP->worldRectOffset + dstBlitRect.left) << b2) & 31;
  1413.     remainBits = ((dstBlitRect.right - dstBlitRect.left) << b2) & 31;
  1414.         
  1415.         // calculate the number of bytes to blit
  1416.     numBytesPerRow =((dstBlitRect.right - dstBlitRect.left) >> b1) * sizeof(long);
  1417.     
  1418.         // calculate the number of rows to blit
  1419.     numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;
  1420.  
  1421.         // calculate the row offsets
  1422.     srcOffset = srcFrameP->frameRowBytes;
  1423.     dstOffset = dstFrameP->frameRowBytes;
  1424.  
  1425.     if ( interlaced )
  1426.     {
  1427.         // skip first row if it's wrong kind (even/odd)
  1428.         if ( ((dstBlitRect.top - frameRect->top) & 1) == dstFrameP->skipOddLines )
  1429.         {
  1430.             srcBlitRect.top++;
  1431.             dstBlitRect.top++;
  1432.             numRowsToCopy--;
  1433.         }
  1434.         
  1435.         numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  1436.         if (numRowsToCopy < 1)
  1437.             return;
  1438.  
  1439.         // Double the row offsets since we're skipping every other line
  1440.         srcOffset += srcOffset;
  1441.         dstOffset += dstOffset;
  1442.     }
  1443.     
  1444.         // The offsets push the pixel pointer from the end of one row
  1445.         // to the beginning of the next. 
  1446.     srcOffset -= numBytesPerRow;
  1447.     dstOffset -= numBytesPerRow;
  1448.  
  1449.     START_32_BIT_MODE
  1450.  
  1451.     srcBaseOffset =    SW_ROWBYTES( srcFrameP, srcBlitRect.top ) +    ((srcBlitRect.left >> b1) * sizeof(long));
  1452.     
  1453.     BlitPixieAllBitMask(
  1454.         (UInt8 *) (srcFrameP->frameBaseAddr + srcBaseOffset ),
  1455.         (UInt8 *) (dstFrameP->frameBaseAddr + SW_ROWBYTES(dstFrameP,dstBlitRect.top) + ((dstBlitRect.left >> b1) * sizeof(long)) ),
  1456.         (UInt8 *) (srcFrameP->maskBaseAddr + srcBaseOffset ),
  1457.         srcOffset,
  1458.         dstOffset,
  1459.         numBytesPerRow,
  1460.         numRowsToCopy,
  1461.         srcBitOffset,
  1462.         dstBitOffset,
  1463.         remainBits
  1464.         );
  1465.  
  1466.     END_32_BIT_MODE
  1467. #endif
  1468. }
  1469.  
  1470.  
  1471. ///--------------------------------------------------------------------------------------
  1472. //    BlitPixieAllBitPartialMaskDrawProc
  1473. ///--------------------------------------------------------------------------------------
  1474.  
  1475. SW_FUNC void BlitPixieAllBitPartialMaskDrawProc(
  1476.     FramePtr srcFrameP,
  1477.     FramePtr dstFrameP,
  1478.     Rect* srcRect,
  1479.     Rect* dstRect)
  1480. {
  1481. #if SW_PPC
  1482. #pragma unused(srcFrameP, dstFrameP, srcRect, dstRect)
  1483.     SW_ASSERT(SW_68K);
  1484. #else
  1485.     Rect                srcBlitRect = *srcRect;
  1486.     Rect                dstBlitRect = *dstRect;
  1487.     RectPtr                frameRect = &dstFrameP->frameRect;
  1488.     Boolean                interlaced = dstFrameP->interlacingIsOn;
  1489.     unsigned long        srcBaseOffset;
  1490.     unsigned long        numBytesPerRow;
  1491.     unsigned long         numRowsToCopy;
  1492.     unsigned long        srcOffset;
  1493.     unsigned long        dstOffset;
  1494.     short                pixelSize, b1, b2;
  1495.     short                srcBitOffset,dstBitOffset,remainBits;
  1496.     
  1497.     SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
  1498.     SW_ASSERT(srcFrameP->maskPort != NULL);
  1499.     
  1500.     BP_CLIP_RECT(frameRect, srcBlitRect, dstBlitRect );
  1501.  
  1502.         // Make sure height is valid
  1503.     if (dstBlitRect.bottom <= dstBlitRect.top)
  1504.         return;
  1505.         // Make sure width is valid
  1506.     if (dstBlitRect.right <= dstBlitRect.left)
  1507.         return;
  1508.         
  1509.     pixelSize = dstFrameP->frameDepth;
  1510.     switch ( pixelSize )
  1511.     {
  1512.         case 1:        b1 = 5;        break;        // 1-bit:  32 pixels per long ( 1 << 5 == 32)
  1513.         case 2:        b1 = 4;        break;        // 2-bit:  16 pixels per long ( 1 << 4 == 16)
  1514.         case 4:        b1 = 3;        break;        // 4-bit:   8 pixels per long ( 1 << 3 ==  8)
  1515.         case 8:        b1 = 2;        break;        // 8-bit:   4 pixels per long ( 1 << 2 ==  4)
  1516.         case 16:    b1 = 1;        break;        // 16-bit:  2 pixels per long ( 1 << 1 ==  2)
  1517.         case 32:    b1 = 0;        break;        // 32-bit:  1 pixels per long ( 1 << 0 ==  1)
  1518.  
  1519.         default:                return;        // unknown depth, abort
  1520.     }
  1521.     b2 = 5 - b1;
  1522.  
  1523.         // calculate any odd (non-byte) number of bits
  1524.     srcBitOffset = ((srcFrameP->worldRectOffset + srcBlitRect.left) << b2) & 31;
  1525.     dstBitOffset = ((dstFrameP->worldRectOffset + dstBlitRect.left) << b2) & 31;
  1526.     remainBits = ((dstBlitRect.right - dstBlitRect.left) << b2) & 31;
  1527.  
  1528.     remainBits = ((dstBlitRect.right - dstBlitRect.left) << b2) & 31;
  1529.  
  1530.         // calculate the number of bytes to blit
  1531.     numBytesPerRow = ((dstBlitRect.right - dstBlitRect.left) >> b1) * sizeof(long);
  1532.     
  1533.         // calculate the number of rows to blit
  1534.     numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;
  1535.  
  1536.         // calculate the row offsets
  1537.     srcOffset = srcFrameP->frameRowBytes;
  1538.     dstOffset = dstFrameP->frameRowBytes;
  1539.  
  1540.     if ( interlaced )
  1541.     {
  1542.         // skip first row if it's wrong kind (even/odd)
  1543.         if ( ((dstBlitRect.top - frameRect->top) & 1) == dstFrameP->skipOddLines )
  1544.         {
  1545.             srcBlitRect.top++;
  1546.             dstBlitRect.top++;
  1547.             numRowsToCopy--;
  1548.         }
  1549.         
  1550.         numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  1551.         if (numRowsToCopy < 1)
  1552.             return;
  1553.  
  1554.         // Double the row offsets since we're interlaced
  1555.         srcOffset += srcOffset;
  1556.         dstOffset += dstOffset;
  1557.     }
  1558.     
  1559.         // The offsets push the pixel pointer from the end of one row
  1560.         // to the beginning of the next. 
  1561.     srcOffset -= numBytesPerRow;
  1562.     dstOffset -= numBytesPerRow;
  1563.  
  1564.     START_32_BIT_MODE
  1565.     
  1566.     srcBaseOffset =    SW_ROWBYTES( srcFrameP, srcBlitRect.top ) + ((srcBlitRect.left >> b1) * sizeof(long));
  1567.     
  1568.     BlitPixieAllBitPartialMask(
  1569.         (UInt8 *) (srcFrameP->frameBaseAddr + srcBaseOffset ),
  1570.         (UInt8 *) (dstFrameP->frameBaseAddr + SW_ROWBYTES(dstFrameP,dstBlitRect.top) + ((dstBlitRect.left >> b1) * sizeof(long)) ),
  1571.         (UInt8 *) (srcFrameP->maskBaseAddr + srcBaseOffset ),
  1572.         srcOffset,
  1573.         dstOffset,
  1574.         numBytesPerRow,
  1575.         numRowsToCopy,
  1576.         srcBitOffset,
  1577.         dstBitOffset,
  1578.         remainBits
  1579.         );
  1580.  
  1581.     END_32_BIT_MODE
  1582. #endif
  1583. }
  1584.  
  1585. #pragma mark -
  1586.  
  1587. ///--------------------------------------------------------------------------------------
  1588. //    SWGetValueFromColor
  1589. ///--------------------------------------------------------------------------------------
  1590.  
  1591. SW_FUNC unsigned long SWGetValueFromColor(
  1592.     FramePtr dstFrameP,
  1593.     RGBColor *color)
  1594. {
  1595.     GWorldPtr    saveGWorld;
  1596.     GDHandle    saveGDevice;
  1597.     UInt32        pixelValue;
  1598.     
  1599.     SW_ASSERT(dstFrameP != NULL);
  1600.     SW_ASSERT(dstFrameP->framePort != NULL);
  1601.     
  1602.     GetGWorld( &saveGWorld, &saveGDevice );
  1603.     SetGWorld( dstFrameP->framePort, dstFrameP->frameDevice );
  1604.     
  1605.         // convert RGBColor to pixel value
  1606.     pixelValue = Color2Index( color );
  1607.     
  1608.         // repeat to fill the entire word, as required by the fill functions
  1609.     if ( dstFrameP->frameDepth < 16 )
  1610.         pixelValue |= pixelValue << 8;
  1611.     if ( dstFrameP->frameDepth < 32 )
  1612.         pixelValue |= pixelValue << 16;
  1613.  
  1614.     SetGWorld( saveGWorld, saveGDevice );
  1615.     return pixelValue;
  1616. }
  1617.  
  1618.  
  1619. ///--------------------------------------------------------------------------------------
  1620. //    SWGetColorFromValue
  1621. ///--------------------------------------------------------------------------------------
  1622.  
  1623. SW_FUNC void SWGetColorFromValue(
  1624.     FramePtr dstFrameP,
  1625.     RGBColor *color,
  1626.     unsigned long pixelValue)
  1627. {
  1628.     GWorldPtr    saveGWorld;
  1629.     GDHandle    saveGDevice;
  1630.     
  1631.     SW_ASSERT(dstFrameP != NULL);
  1632.     SW_ASSERT(dstFrameP->framePort != NULL);
  1633.     
  1634.     GetGWorld( &saveGWorld, &saveGDevice );
  1635.     SetGWorld( dstFrameP->framePort, dstFrameP->frameDevice );
  1636.     
  1637.         // truncate pixel value to max allowed, in case it was repeated before
  1638.     if ( dstFrameP->frameDepth < 32 )
  1639.         pixelValue &= ( 1L << dstFrameP->frameDepth ) - 1L;
  1640.     
  1641.         // convert RGBColor to pixel value
  1642.     Index2Color( pixelValue, color );
  1643.     
  1644.     SetGWorld( saveGWorld, saveGDevice );
  1645. }
  1646.  
  1647.  
  1648. ///--------------------------------------------------------------------------------------
  1649. //    SWSetPixel
  1650. ///--------------------------------------------------------------------------------------
  1651.  
  1652. SW_FUNC void SWSetPixel(
  1653.     FramePtr        dstFrameP,
  1654.     short            x,
  1655.     short            y,
  1656.     unsigned long    color)
  1657. {
  1658.     SW_ASSERT( dstFrameP->isFrameLocked );
  1659.     SW_ASSERT( x >= dstFrameP->frameRect.left && x < dstFrameP->frameRect.right );
  1660.     SW_ASSERT( y >= dstFrameP->frameRect.top  && y < dstFrameP->frameRect.bottom );
  1661.  
  1662.     START_32_BIT_MODE
  1663.  
  1664.     switch ( dstFrameP->frameDepth )
  1665.     {
  1666.         case 1 :
  1667.             if ( color )
  1668.                 SW_BITSET( dstFrameP->frameBaseAddr + SW_ROWBYTES( dstFrameP, y ), x );
  1669.             else
  1670.                 SW_BITCLR( dstFrameP->frameBaseAddr + SW_ROWBYTES( dstFrameP, y ), x );
  1671.             break;
  1672.         case 4 :
  1673.             SW_NIBBLESET( dstFrameP->frameBaseAddr + SW_ROWBYTES( dstFrameP, y ), x, color );
  1674.             break;
  1675.         case 8 :
  1676.             *SW_PIXELPTR8( dstFrameP, x, y ) = color;
  1677.             break;
  1678.         case 16 :
  1679.             *SW_PIXELPTR16( dstFrameP, x, y ) = color;
  1680.             break;
  1681.         case 32 :
  1682.             *SW_PIXELPTR32( dstFrameP, x, y ) = color;
  1683.             break;
  1684.         default:
  1685.             {
  1686.                 RGBColor    rgb;
  1687.                 GWorldPtr    saveGWorld;
  1688.                 GDHandle    saveGDevice;
  1689.     
  1690.                 // Note: Need to set port to frame for this to work
  1691.                 GetGWorld( &saveGWorld, &saveGDevice );
  1692.                 SetGWorld( dstFrameP->framePort, dstFrameP->frameDevice );
  1693.                 Index2Color( color, &rgb );
  1694.                 SetCPixel( x, y, &rgb );
  1695.                 SetGWorld( saveGWorld, saveGDevice );
  1696.             }
  1697.             break;
  1698.     }
  1699.     
  1700.     END_32_BIT_MODE
  1701. }
  1702.  
  1703.  
  1704. ///--------------------------------------------------------------------------------------
  1705. //    SWGetPixel
  1706. ///--------------------------------------------------------------------------------------
  1707.  
  1708. SW_FUNC unsigned long SWGetPixel(
  1709.     FramePtr        srcFrameP,
  1710.     short            x,
  1711.     short            y )
  1712. {
  1713.     unsigned long    val;
  1714.     
  1715.     SW_ASSERT( srcFrameP->isFrameLocked );
  1716.     SW_ASSERT( x >= srcFrameP->frameRect.left && x < srcFrameP->frameRect.right );
  1717.     SW_ASSERT( y >= srcFrameP->frameRect.top  && y < srcFrameP->frameRect.bottom );
  1718.  
  1719.     START_32_BIT_MODE
  1720.  
  1721.     switch ( srcFrameP->frameDepth )
  1722.     {
  1723.         case 1 :
  1724.             val = SW_BITTST( srcFrameP->frameBaseAddr + SW_ROWBYTES( srcFrameP, y ), x );
  1725.         case 4 :
  1726.             val = SW_NIBBLEGET( srcFrameP->frameBaseAddr + SW_ROWBYTES( srcFrameP, y ), x );
  1727.         case 8 :
  1728.             val = *SW_PIXELPTR8( srcFrameP, x, y ); 
  1729.         case 16 :
  1730.             val = *SW_PIXELPTR16( srcFrameP, x, y ); 
  1731.         case 32 :
  1732.             val = *SW_PIXELPTR32( srcFrameP, x, y ); 
  1733.         default:
  1734.             {
  1735.                 RGBColor        rgb;
  1736.                 GWorldPtr        saveGWorld;
  1737.                 GDHandle        saveGDevice;
  1738.                 
  1739.                 // Note: Need to set port to frame for this to work
  1740.                 GetGWorld( &saveGWorld, &saveGDevice );
  1741.                 SetGWorld( srcFrameP->framePort, srcFrameP->frameDevice );
  1742.                 GetCPixel( x, y, &rgb );
  1743.                 val = Color2Index( &rgb );
  1744.                 SetGWorld( saveGWorld, saveGDevice );
  1745.             }
  1746.     }
  1747.     
  1748.     END_32_BIT_MODE
  1749.     
  1750.     return val;
  1751. }
  1752.  
  1753.  
  1754. ///--------------------------------------------------------------------------------------
  1755. //    SWAnimateStarField
  1756. ///--------------------------------------------------------------------------------------
  1757.  
  1758. SW_FUNC void SWAnimateStarField(
  1759.     SpriteWorldPtr    spriteWorldP,
  1760.     StarArray        *starArray,
  1761.     short            numStars,
  1762.     unsigned long    backColor)
  1763. {
  1764.     short            curStar;
  1765.     short            horizOffset, vertOffset;    // Offset from window to work area
  1766.     FramePtr        windFrameP = spriteWorldP->windowFrameP;
  1767.     FramePtr        workFrameP = spriteWorldP->workFrameP;
  1768.     StarArrayPtr    curStarP;
  1769.     int                x, y;
  1770.     
  1771.     SW_ASSERT(windFrameP->isFrameLocked && workFrameP->isFrameLocked);
  1772.     SW_ASSERT(spriteWorldP->pixelDepth >= 8);
  1773.  
  1774.         // Stores offset if spriteWorld is smaller than window
  1775.     horizOffset = windFrameP->frameRect.left;
  1776.     vertOffset = windFrameP->frameRect.top;
  1777.  
  1778.         // Get a pointer to the first element in the starArray
  1779.     curStarP = starArray;
  1780.     
  1781.     START_32_BIT_MODE
  1782.  
  1783.     switch ( spriteWorldP->pixelDepth )
  1784.     {
  1785.         case 8 :
  1786.             for (curStar = 0; curStar < numStars; curStar++, curStarP++)
  1787.             {
  1788.                     // Erase the star only if it was drawn last frame.
  1789.                 if (curStarP->needsToBeErased)
  1790.                 {
  1791.                     x = curStarP->oldHorizLoc;
  1792.                     y = curStarP->oldVertLoc;
  1793.                     *SW_PIXELPTR8( windFrameP, x, y ) = backColor; 
  1794.                 }
  1795.                 
  1796.                 if (curStarP->isOn)
  1797.                 {
  1798.                     x = curStarP->horizLoc;
  1799.                     y = curStarP->vertLoc;
  1800.                     
  1801.                         // Make sure we aren't going to draw over a sprite
  1802.                     if ( *SW_PIXELPTR8( workFrameP, x, y ) == backColor )
  1803.                     {
  1804.                         // Draw the new star position
  1805.                         *SW_PIXELPTR8( windFrameP, x, y ) = curStarP->color; 
  1806.                     
  1807.                         curStarP->needsToBeErased = true;
  1808.                     }
  1809.                     else
  1810.                     {
  1811.                         curStarP->needsToBeErased = false;
  1812.                     }
  1813.                 }
  1814.                 else
  1815.                 {
  1816.                     curStarP->needsToBeErased = false;
  1817.                 }
  1818.             }
  1819.             break;
  1820.         case 16:
  1821.             for (curStar = 0; curStar < numStars; curStar++, curStarP++)
  1822.             {
  1823.                     // Erase the star only if it was drawn last frame.
  1824.                 if (curStarP->needsToBeErased)
  1825.                 {
  1826.                     x = curStarP->oldHorizLoc;
  1827.                     y = curStarP->oldVertLoc;
  1828.                     *SW_PIXELPTR16( windFrameP, x, y ) = backColor; 
  1829.                 }
  1830.                 
  1831.                 if (curStarP->isOn)
  1832.                 {
  1833.                     x = curStarP->horizLoc;
  1834.                     y = curStarP->vertLoc;
  1835.                     
  1836.                         // Make sure we aren't going to draw over a sprite
  1837.                     if ( *SW_PIXELPTR16( workFrameP, x, y ) == backColor )
  1838.                     {
  1839.                         // Draw the new star position
  1840.                         *SW_PIXELPTR16( windFrameP, x, y ) = curStarP->color; 
  1841.                     
  1842.                         curStarP->needsToBeErased = true;
  1843.                     }
  1844.                     else
  1845.                     {
  1846.                         curStarP->needsToBeErased = false;
  1847.                     }
  1848.                 }
  1849.                 else
  1850.                 {
  1851.                     curStarP->needsToBeErased = false;
  1852.                 }
  1853.             }
  1854.             break;
  1855.         case 32:
  1856.             for (curStar = 0; curStar < numStars; curStar++, curStarP++)
  1857.             {
  1858.                     // Erase the star only if it was drawn last frame.
  1859.                 if (curStarP->needsToBeErased)
  1860.                 {
  1861.                     x = curStarP->oldHorizLoc;
  1862.                     y = curStarP->oldVertLoc;
  1863.                     *SW_PIXELPTR32( windFrameP, x, y ) = backColor; 
  1864.                 }
  1865.                 
  1866.                 
  1867.                 if (curStarP->isOn)
  1868.                 {
  1869.                     x = curStarP->horizLoc;
  1870.                     y = curStarP->vertLoc;
  1871.                     
  1872.                         // Make sure we aren't going to draw over a sprite
  1873.                     if ( *SW_PIXELPTR32( workFrameP, x, y ) == backColor )
  1874.                     {
  1875.                         // Draw the new star position
  1876.                         *SW_PIXELPTR32( windFrameP, x, y ) = curStarP->color; 
  1877.                     
  1878.                         curStarP->needsToBeErased = true;
  1879.                     }
  1880.                     else
  1881.                     {
  1882.                         curStarP->needsToBeErased = false;
  1883.                     }
  1884.                 }
  1885.                 else
  1886.                 {
  1887.                     curStarP->needsToBeErased = false;
  1888.                 }
  1889.             }
  1890.             break;
  1891.     }
  1892.     
  1893.     END_32_BIT_MODE
  1894. }
  1895.  
  1896.